#!/usr/bin/env python
# razvan.coca@gmail.com
from optparse import OptionParser
import pprint
import time
import re
import sys,os,glob
from xml.dom import minidom
import StringIO
import config

def LoadConfig(ConfigFile):
    f=open(ConfigFile,'r')
    fd=StringIO.StringIO(f.read())
    f.close()
    cfg = config.Config()
    cfg.load(fd)
    fd.close()
    return cfg

def isLayer(p):
    return type(p)==config.Mapping or type(p)==config.Config
def isTextNode(node):
    return node.nodeType==1 and node.hasAttribute('TEXT') 

def ConfigToMindMap(Config):
    xmltree=minidom.Document()
    Map=xmltree.createElement("map")
    Map.setAttribute("version","0.9.0")
    Parent=xmltree.appendChild(Map)
    xqueue=[Parent]
    queue=[Config]
    i=0
    while(len(queue)):
        top=queue.pop(0)
        Parent=xqueue.pop(0)
        if type(top)==config.Config or type(top)==config.Mapping:
            for item in top.iterkeys():
                #print i,item, top[item],type(top[item])
                if type(top[item])==config.Mapping:
                    node=xmltree.createElement("node")
                    node.setAttribute("TEXT",item)
                    node.setAttribute("STYLE","bubble")
                    P=Parent.appendChild(node)
                if type(top[item])!=config.Mapping:
                        #print "leaf:",i,top,item, top[item],type(top[item])
                        attr=xmltree.createElement("attribute")
                        attr.setAttribute("NAME",item)
                        attr.setAttribute("VALUE",top[item])
                        P=Parent.appendChild(attr)
                xqueue.append(P)
                queue.append(top[item])
                    
        i+=1            
    return xmltree


def printXmlTree(xmltree):
    queue=[xmltree]
    while(len(queue)):
        top=queue.pop(0)
        print top,isTextNode(top)
        if isTextNode(top):
            name=top.getAttribute('TEXT').encode("ascii")
            print name
        for item in top.childNodes:
            if isTextNode(item):
                name=item.getAttribute('TEXT').encode("ascii")
            queue.append(item)


def RecurseMindMapToConfig(xml_node,Parent=config.Config()):
    if isTextNode(xml_node):
        name=getTEXT(xml_node)
        Parent.addMapping(name,config.Mapping(name),None)
        attrs=filter(lambda x:"attribute"==x.nodeName,xml_node.childNodes)
        if len(attrs):
            for attr in attrs:
                key=getNAME(attr)
                value=getVALUE(attr)
                #print "attr:",key,value
                Parent[name].addMapping(key,value,None)
        Parent=Parent[name]
    for item in xml_node.childNodes:
            RecurseMindMapToConfig(item,Parent=Parent)

def MindMapToConfig(xmltree):
        cfg=config.Config()
        RecurseMindMapToConfig(xmltree,Parent=cfg)
        return cfg


def getVALUE(attr):
    return attr.getAttribute("VALUE").encode("ascii")

def getNAME(attr):
    return attr.getAttribute("NAME").encode("ascii")

def getTEXT(item):
    return item.getAttribute('TEXT').encode('ascii')

def ConfigToMM(ConfigFile,MMFile):
    cfg=LoadConfig(ConfigFile)
    xmltree=ConfigToMindMap(cfg)
    with open(MMFile,"wt+") as FD:
        print>>FD,xmltree.toprettyxml().replace('<?xml version="1.0" ?>','')

def MMtoConfig(MMFile,ConfigFile):
    xmltree=minidom.parse(MMFile)
    #printXmlTree(xmltree)
    cfg=MindMapToConfig(xmltree)
    with open(ConfigFile,"wt+") as FD:
        cfg.save(FD)

WD=os.getenv('PWD')
os.chdir(WD)
sys.path.append(os.getcwd())


def Propagate(ConfigFile):
    cfg=LoadConfig(ConfigFile)
    PropagateServiceInSubtree(cfg)
    PropagateStrandsInSubtree(cfg)
    #print cfg
    with open(ConfigFile,'w') as f:
        cfg.save(f)


if __name__=='__main__':
    parser=OptionParser()
    parser.add_option('-c','--config',type="string")
    parser.add_option('-m','--mindmap',type="string")#,default="xxx.mm")
    parser.add_option('-p','--propagate',type='string')
        
    (options,args) = parser.parse_args()
    if options.config and os.access(options.config,os.R_OK):
        mapfile=options.config.replace(".config",".mm")
        print "Translating %s to %s"%(options.config,mapfile)
        ConfigToMM(options.config,mapfile)
    elif options.mindmap and os.access(options.mindmap,os.R_OK):
        cfgfile=options.mindmap.replace(".mm",".config")
        print "Translating %s to %s"%(options.mindmap,cfgfile)
        MMtoConfig(options.mindmap,cfgfile)
    elif options.propagate and os.access(options.propagate,os.R_OK):
        from AsyncComposer import *
        Propagate(options.propagate)
        print "Propagating services and strands %s" % (options.propagate)
    else:
        parser.print_help()
        exit(2)
    print "Done."
